package com.algorithm.cn.linkedlist;
/**
 * 
 * @author wangzonghui
 * @date 2020-12-22 20:51:39
 * @Description: 双向链表模型
 */
public class DoubleLinkedListDemo {
	
	public static void main(String[] args) {
		System.out.println("双向链表功能测试");
		
		HeroNode2 heroNode1 = new HeroNode2(1,"宋江","及时雨");
		HeroNode2 heroNode2 = new HeroNode2(2,"卢俊义","玉麒麟");
		HeroNode2 heroNode3 = new HeroNode2(3,"吴用","智多星");
		HeroNode2 heroNode4 = new HeroNode2(4,"林冲","豹子头");
		
		DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
		//加入
		doubleLinkedList.add(heroNode1);
		doubleLinkedList.add(heroNode2);
		doubleLinkedList.add(heroNode3);
		doubleLinkedList.add(heroNode4);
		
		doubleLinkedList.List();
		
		System.out.println("~修改~");
		HeroNode2 newHeroNode = new HeroNode2(2,"小卢","玉麒麟~~");
		doubleLinkedList.update(newHeroNode);
		doubleLinkedList.List();
		
		System.out.println("~删除~");
		doubleLinkedList.del(3);
		doubleLinkedList.List();
	}

}

class DoubleLinkedList{
	
	//初始化头结点，头结点不存放具体数据
	private HeroNode2 head=new HeroNode2(0, "", "");
		
	public HeroNode2 getHead() {
		return head;
	}
	
	
	/**
	 * 遍历双向链表
	 */
	public void List() {
		if(head.next==null) {
			System.out.println("链表为空");
			return;
		}
		
		HeroNode2 tmp=head.next;
		while(true) {
			//找到最后一个结点
			if(tmp==null) {
				break;
			}
			System.out.println(tmp);
			//如果没有找到最后
			tmp=tmp.next;
		}
	}
	
	/**
	 * 添加结点向双单向链表
	 * 1. 找当前链表的最后结点
	 * 2. 将最后结点的next指向新结点
	 * 3. 新结点的pre指向最后结点
	 * @param hernoe
	 */
	public void add(HeroNode2 heroNode) {
		
		HeroNode2 tmp=head;
		while(true) {
			//找到最后一个结点
			if(tmp.next==null) {
				break;
			}
			//后移
			tmp=tmp.next;
			
		}
		tmp.next=heroNode;
		heroNode.pre=tmp;
	}
	
	/**
	 * 修改 根据标号修改和单向链表一样
	 * @param heroNode
	 */
	public void update(HeroNode2 newHeroNode) {
		//判断是否为空
		if(head.next==null) {
			System.out.println("链表为空");
			return;
		}
		
		//找到需要修改的结点
		HeroNode2 tmp=head.next;
		boolean flag=false;  //表示是否找到
		while(true) {
			//链表遍历结束
			if(tmp==null) {
				break;
			}
			
			//找到
			if(tmp.no==newHeroNode.no) {
				flag=true;
				break;
			}
			
			tmp=tmp.next;
		}
		
		if(flag) {
			tmp.name=newHeroNode.name;
			tmp.nickName=newHeroNode.nickName;
			
		}else {  //没有找到
			System.out.printf("没有找到 编号%d 的结点，不能修改",newHeroNode.no);
		}
	}
	
	/**
	 * 删除节点
	 * 1. 找到双向链表的
	 * 2. 实现自我删除
	 * @param newHeroNode
	 */
	public void del(int no) {
		//判断是否为空
		if(head.next==null) {
			System.out.println("链表为空，无法删除");
			return;
		}
				
		//找到需要修改的结点
		HeroNode2 tmp=head.next;
		boolean flag=false;  //表示是否找到
		while(true) {
			//链表遍历结束
			if(tmp==null) {
				break;
			}
			
			//找到
			if(tmp.no==no) {
				flag=true;
				break;
			}
			
			tmp=tmp.next;
		}
		
		if(flag) {  //删除
			tmp.pre.next=tmp.next;
			if(tmp.next!=null) {
				tmp.next.pre=tmp.pre;
			}
			
		}else {  //没有找到
			System.out.printf("没有找到 编号%d 的结点，不能删除",no);
		}
	}
}


class HeroNode2{
	
	public int no;
	public String name;
	public String nickName;
	public HeroNode2 next;  //指向下一个结点
	public HeroNode2 pre;  //指向上一个节点
	
	public HeroNode2(int no,String name,String nickName) {
		this.no=no;
		this.name=name;
		this.nickName=nickName;
	}
	
	@Override
	public String toString() {
		return "HeroNode [no=" + no + ", name=" + name + ", nickName=" + nickName + "]";
	}
}